package uk.ac.ebi.uniprot.wikipedia.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 * User: ljgarcia
 * Date: 10/07/12
 * Time: 14:30
 * To change this template use File | Settings | File Templates.
 */
public class AccessionResolver {
    /**
     * Regular expression for checking / extracting the details of a valid
     * uniprot accession.
     * <br>
     * Group 1: Accession itself (e.g. Q12345)
     * <br>
     * Group 3: Version number if present.
     */
    private static final Pattern UNIPROT_ACCESSION_PATTERN = Pattern.compile("^([A-Z]\\d\\w{3}\\d)(-(\\d+))?$");

    /**
     * Regular expression for checking that the segmentId conforms to a swiss-prot name.
     */
    public static final Pattern UNIPROT_ID_PATTERN = Pattern.compile("^\\w+_\\w+$");

    /**
     * Verifies whether the supplied identifier is a valid Uniprot identifier
     *
     * @param segmentId - User supplied (is either accession or name)
     * @return - returns true if the identifier is recognized as being a uniprot identifeir, false otherwise
     */
    public static boolean isUniProtIdentifier(String segmentId) {

        if (segmentId != null) {
            Matcher uniprotAccessionMatcher = UNIPROT_ACCESSION_PATTERN.matcher(segmentId);

            if (uniprotAccessionMatcher.find()) {
                return true;
            } else {
                Matcher uniprotIDMatcher = UNIPROT_ID_PATTERN.matcher(segmentId);

                if (uniprotIDMatcher.find()) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Parses out the uniprot accession, leaving out any version number that has been appended.
     * It does not throw a BadReferenceObject Exception because methods using this one,
     * will interpret a null return as an indication to treat the segment id as an identifier rather than an accession.
     * @param segmentId - String used to identify the entry you want to retrieve
     * @return a String array containing the primary accession and any isoform if existing.
     *         Returns null if no entry contains the referenced accession
     */
    public static String[] parseUniprotAccession(String segmentId) {

        Matcher uniprotAccessionMatcher = UNIPROT_ACCESSION_PATTERN.matcher(segmentId);

        if (uniprotAccessionMatcher.find()) {
            //first cell contains primary accession, second cell contains isoform reference
            return new String[]{uniprotAccessionMatcher.group(1), uniprotAccessionMatcher.group(3)};
        } else
            return null;
    }
}
